package ejb.managerbeans;

import javax.ejb.Stateless;

import ejb.dto.UserDTO;
import ejb.entities.*;
import ejb.managerbeans.UserManagerBeanLocal;
import ejb.utility.ConvertDTO;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJBContext;
import javax.persistence.EntityExistsException;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;


/**
 * Session Bean implementation class UserManagerBean
 */
@Stateless
public class UserManagerBean implements UserManagerBeanLocal 
{

	@PersistenceContext
    private EntityManager em;
	
	@Resource
	private EJBContext context;
	
    /**
     * Default constructor. 
     */
    public UserManagerBean() {
    }
    
    
    @Override
	public void save( UserDTO userDTO ) 
    {
		User newUser = new User(userDTO);
		
		List<Group> groups = new ArrayList<Group>();
		
		//cerca l'oggetto Group da inserire nella lista dei gruppi degli utenti e associo all'utente
		Group g = ( Group ) em.createNamedQuery( Group.FINDBYNAME, Group.class ).setParameter( "id", "USERS" ).getSingleResult();
		groups.add( g );
		newUser.setGroups(groups);
		
		g.getUsers().add( newUser );
		
		//creo nuova giftlist di default da associare al nuovo utente (USER) registrato
		Giftlist gl = new Giftlist();
		gl.setName( "GiftList di " + userDTO.getEmail() );
		
		//associo alla giftlist il nuovo utente
		gl.setUser( newUser );
		
		//associo al nuovo utente la giftlist di default
		List<Giftlist> gls = new ArrayList<Giftlist>();
		gls.add( gl );
		newUser.setGiftlists( gls );
		
		try
		{
			em.persist(newUser);
			em.persist( gl );
		}
		catch( EntityExistsException e )
		{	
		}	
	}
    
    @Override
	@RolesAllowed({Group.USER,Group.ADMIN})
	public void update(UserDTO user)
    {
    	//cerca l'utente nel db
    	//se lo trova aggiorna i dati altrimenti niente
    	if( !em.createNamedQuery( User.FINDBYID, User.class ).setParameter( "id", user.getEmail() ).getResultList().isEmpty() )
    		em.merge( new User(user) );
	}
    
    @Override
	@RolesAllowed({Group.USER})
	public void unregister() 
    { 	
    	remove(getPrincipalUser());
	}
    
    public User getPrincipalUser() {
    	return find(getPrincipalEmail());
    }
    
    public String getPrincipalEmail() 
    {
    	return context.getCallerPrincipal().getName();
    }
    
    public void remove(User user) 
    {
    	em.remove(user);
	}
    
    public User find(String email) {
    	return em.find( User.class, email );
    }
    
    @Override
	@RolesAllowed({Group.USER,Group.ADMIN})
	public UserDTO getUserDTOLogged() {
		UserDTO userDTO = ConvertDTO.convertToDTOUser(getPrincipalUser());
		return userDTO;
	}

    public List<User> getAllUsers() {
    	return em.createNamedQuery(User.FIND_ALL, User.class)
                .getResultList();
    }
    
    
    /**
     * @author Daniele Montesano
     * @return 
    */
    @Override
    public List<UserDTO> getAllUsersDTO()
    {
    	List<UserDTO> usersDTO = new ArrayList<UserDTO>();
    	List<User> users = getAllUsers();
    	
    	for( User u : users )
    		usersDTO.add( ConvertDTO.convertToDTOUser( u ) );
    	
    	return usersDTO;
    }
    
    @Override
    public UserDTO getUserDTO( String email )
    {
    	try
    	{
    		User u = ( User ) em.createNamedQuery( User.FINDBYID, User.class ).setParameter( "id", email).getSingleResult();
    		
    		return ConvertDTO.convertToDTOUser( u );
    	}
    	catch( NoResultException e )
    	{
    		return null;
    	}
    }


	/*public List<User> getAllUsersRegistred()
    {
    	return em.createNamedQuery( );
    }*/

}
